package com.lanyan.system.controller.api;

import com.lanyan.common.annotation.RepeatSubmit;

import java.math.BigDecimal;

import com.lanyan.common.utils.SecurityUtils;
import com.lanyan.system.domain.Account;
import com.lanyan.system.domain.BalanceHistory;
import com.lanyan.system.domain.vo.AccountVo;
import com.lanyan.system.service.IAccountService;
import com.lanyan.system.service.IBalanceHistoryService;
import com.lanyan.web.controller.TransferToUser;
import com.lanyan.web.controller.pay.PayReturnVO;
import io.swagger.annotations.Api;

import java.util.List;
import java.util.Map;
import java.util.Set;

import com.lanyan.common.core.domain.R;
import com.lanyan.common.core.domain.PageR;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.lanyan.common.annotation.Log;
import io.swagger.annotations.ApiOperation;
import com.lanyan.common.core.controller.BaseController;
import com.lanyan.common.enums.BusinessType;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import springfox.documentation.annotations.ApiIgnore;
import com.lanyan.common.utils.StringUtils;
import com.lanyan.system.domain.Withdraw;
import com.lanyan.system.domain.vo.WithdrawVo;
import com.lanyan.system.service.IWithdrawService;

/**
 * 提现Controller
 *
 * @author lanyan
 * @date 2024-11-26
 */
@RestController
@Api(tags = {"提现"})
@RequestMapping("/api/withdraw")
public class ApiWithdrawController extends BaseController {
    @Autowired
    private IWithdrawService withdrawService;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private IBalanceHistoryService balanceHistoryService;
    @Autowired
    @Lazy
    private TransferToUser transferToUser;

    /**
     * 查询提现列表
     */
    @GetMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "第几页", dataType = "int", dataTypeClass = int.class),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", dataTypeClass = int.class),
    })
    @ApiOperation("查询提现列表")
    public PageR<Withdraw> list(@ApiIgnore Withdraw withdraw) {
        startPage();
        withdraw.setAccountId(SecurityUtils.getUserId());
        List<Withdraw> list = withdrawService.selectWithdrawList(withdraw);
        return PageR.page(list);
    }
    /**
     * 新增提现
     */
    @Log(title = "提现", businessType = BusinessType.INSERT)
    @PostMapping("save")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "money", value = "提现金额", dataType = "BigDecimal", dataTypeClass = BigDecimal.class),
    })
    @RepeatSubmit
    @ApiOperation("新增提现")
    public R<PayReturnVO> add(@ApiIgnore @RequestBody Withdraw withdraw) {
        BigDecimal money = withdraw.getMoney();
        if (money.compareTo(BigDecimal.ZERO) <= 0){
            return R.fail("提现金额不能小于0");
        }
        if (money.compareTo(accountService.getById(SecurityUtils.getUserId()).getBalance()) > 0){
            return R.fail("提现金额不能大于可提现余额");
        }
        if (withdraw.getMoney().compareTo(BigDecimal.valueOf(2000)) > 0){
            return R.fail("提现金额不能大于2000");
        }
        StringUtils.insertRequired(withdraw);
        Long accountId = SecurityUtils.getUserId();
        Account account = accountService.getById(accountId);
        if (account.getBalance().compareTo(withdraw.getMoney()) < 0){
            return R.fail("可提现余额不足");
        }
        //获取当前毫秒值
        long millis = System.currentTimeMillis();
        withdraw.setAccountId(accountId);
        withdraw.setSate("0");
        String outBillNo = millis+"tx"+accountId;
        withdraw.setOutBillNo(outBillNo);
        withdrawService.save(withdraw);
        accountService.lambdaUpdate()
                .eq(AccountVo::getAccountId,accountId)
                .set(AccountVo::getBalance,account.getBalance().subtract(withdraw.getMoney()))
                .update();
        BalanceHistory balanceHistory = new BalanceHistory();
        balanceHistory.setAccountId(accountId);
        balanceHistory.setMessage("申请提现");
        balanceHistory.setTitle("申请提现");
        balanceHistory.setMoney(BigDecimal.ZERO.subtract(withdraw.getMoney()));
        balanceHistory.setType("0");
        balanceHistory.setPointTo(withdraw.getWithdrawId().toString());
        balanceHistoryService.save(balanceHistory);
        //Todo 调用微信商家转账接口
        PayReturnVO payReturnVO = new PayReturnVO();
        payReturnVO.setWithdrawId(withdraw.getWithdrawId());
        //money转成Long类型
        Long transferAmount = withdraw.getMoney().multiply(BigDecimal.valueOf(100)).longValue();
        Map<String, String> map = transferToUser.transferToUser(outBillNo, account.getOpenId(), transferAmount, "用户提现");
        if (map.containsKey("err")){
            withdrawService.lambdaUpdate()
                    .eq(Withdraw::getOutBillNo,outBillNo)
                    .set(Withdraw::getSate,"2")
                    .set(Withdraw::getCause,"提现失败，系统错误!")
                    .update();
            return R.fail("提现失败!");
        }
        Set<Map.Entry<String, String>> entries = map.entrySet();
        String resultInfo = null;
        for (Map.Entry<String, String> entry : entries) {
            resultInfo = entry.getValue();
        }
        payReturnVO.setPackageInfo(resultInfo);
        return R.ok(payReturnVO);
    }

    /**
     * 提现成功
     */
    @Log(title = "提现", businessType = BusinessType.UPDATE)
    @PostMapping("success")
    @ApiOperation("提现成功")
    public R success(@RequestBody PayReturnVO payReturnVO)  {
        Long withdrawId = payReturnVO.getWithdrawId();
        Withdraw withdraw = withdrawService.getById(withdrawId);
        withdraw.setSate("1");
        withdrawService.updateById(withdraw);
        return R.ok();
    }

    /**
     * 获取提现中金额
     */
    @GetMapping("/sum")
    @ApiOperation("获取提现中金额")
    public R<BigDecimal> sum() {
        List<Withdraw> list = withdrawService.lambdaQuery()
                .eq(WithdrawVo::getAccountId, SecurityUtils.getUserId())
                .eq(WithdrawVo::getSate, "0")
                .list();
        BigDecimal sum = list.stream().map(WithdrawVo::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        return R.ok(sum);
    }
}
